# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1069.1.112+1.1069.59.3 -> 1.1069.61.1 # drivers/char/drm-4.0/radeon_drv.c 1.1.1.2 -> 1.4 # drivers/char/drm-4.0/bufs.c 1.1.1.2 -> 1.4 # drivers/char/drm-4.0/tdfx_drv.c 1.2.1.2 -> 1.5 # Makefile 1.190.1.55 -> 1.193.1.32 # drivers/char/drm/r128_cce.c 1.5.1.3 -> 1.12 # drivers/char/drm-4.0/i810_drv.c 1.1.1.2 -> 1.4 # drivers/char/drm/drm_memory.h 1.3.1.3 -> 1.8 # arch/i386/kernel/Makefile 1.6.1.3 -> 1.9.1.1 # drivers/char/drm/radeon_cp.c 1.6.1.3 -> 1.12 # drivers/char/drm/drm_bufs.h 1.5.1.3 -> 1.9 # drivers/scsi/Makefile 1.20.1.3 -> 1.20.1.4 # drivers/char/drm/mga_dma.c 1.4.1.4 -> 1.9 # arch/i386/config.in 1.43.1.5 -> 1.44.1.3 # drivers/char/drm/i810_dma.c 1.7.1.4 -> 1.9.1.3 # drivers/char/drm-4.0/r128_drv.c 1.1.1.2 -> 1.4 # drivers/char/drm-4.0/drmP.h 1.1.1.2 -> 1.4 # arch/i386/kernel/setup.c 1.70.1.5 -> 1.70.1.6 # drivers/char/drm-4.0/gamma_drv.c 1.1.1.2 -> 1.4 # drivers/char/drm-4.0/mga_dma.c 1.1.1.2 -> 1.4 # drivers/char/drm-4.0/ffb_drv.c 1.3.1.2 -> 1.6 # drivers/char/drm-4.0/i810_dma.c 1.3.1.4 -> 1.6.1.2 # drivers/char/drm-4.0/r128_cce.c 1.1.1.2 -> 1.6 # drivers/char/drm/drmP.h 1.9.1.3 -> 1.14 # drivers/char/drm-4.0/mga_drv.c 1.1.1.2 -> 1.4 # drivers/char/drm-4.0/radeon_cp.c 1.1.1.2 -> 1.5 # drivers/char/drm/drm_drv.h 1.4.1.3 -> 1.8 # drivers/char/drm-4.0/memory.c 1.1.1.2 -> 1.4 # Documentation/Configure.help 1.166.1.16 -> 1.166.1.17 # drivers/char/drm/drm_vm.h 1.12.1.4 -> 1.17 # diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help --- a/Documentation/Configure.help Fri Oct 17 15:52:01 2003 +++ b/Documentation/Configure.help Fri Oct 17 15:52:01 2003 @@ -100,6 +100,15 @@ like MGA monitors that you are very unlikely to see on today's systems. +Prompt for advanced kernel configuration options +CONFIG_ADVANCED_OPTIONS + This option will enable prompting for a variety of advanced kernel + configuration options. These options can cause the kernel to not + work if they are set incorrectly, but can be used to optimize certain + aspects of kernel memory management. + + Unless you know what you are doing you *should not* enable this option. + Symmetric Multi-Processing support CONFIG_SMP This enables support for systems with more than one CPU. If you have @@ -20177,6 +20186,15 @@ . The module will be called cpuid.o +x86 BIOS Enhanced Disk Drive support +CONFIG_EDD + Say Y or M here if you want to enable BIOS Enhanced Disk Drive + Services real mode BIOS calls to determine which disk + BIOS tries boot from. This information is then exported via /proc. + + This option is experimental, but believed to be safe, + and most disk controller BIOS vendors do not yet implement this feature. + SBC-60XX Watchdog Timer CONFIG_60XX_WDT This driver can be used with the watchdog timer found on some @@ -24090,6 +24108,38 @@ /proc/sys/dev/mac_hid/mouse_button2_keycode /proc/sys/dev/mac_hid/mouse_button3_keycode +Set high memory pool address +CONFIG_HIGHMEM_START_BOOL + Unless you know what you are doing you *should not* set this option. + + It can be used to override the default PKMAP_BASE address which + is the location of the high memory pool. This can be useful in + optimizing virtual memory usage in a system. + +Set maximum low memory +CONFIG_LOWMEM_SIZE_BOOL + Unless you know what you are doing you *should not* set this option. + + It can be used to override the standard calculated value of + MAX_LOW_MEM. This can be useful in optimizing virtual memory usage + in a system. + +Set custom kernel base address +CONFIG_KERNEL_START_BOOL + Unless you know what you are doing you *should not* set this option. + + It can be used to override the standard PAGE_OFFSET/KERNELBASE + value used by the kernel. This can be useful in controlling + amount of virtual address space available to the kernel. + +Set custom user task size +CONFIG_TASK_SIZE_BOOL + Unless you know what you are doing you *should not* set this option. + + It can be used to override the standard TASK_SIZE value used + by the kernel. This can be useful in controlling amount of + virtual address space available to user tasks. + Enhanced Real Time Clock Support (/dev/rtc) CONFIG_PPC_RTC If you say Y here and create a character special file /dev/rtc with @@ -27146,6 +27196,58 @@ To use this option, you have to check that the "/proc file system support" (CONFIG_PROC_FS) is enabled, too. + +PPC4xx DMA controller support +CONFIG_PPC4xx_DMA + Select this to enable support for the PPC4xx general purpose DMA + controller. + +ttyS0 device +CONFIG_UART0_TTYS0 + This option reverses the mapping between the hardware UART and software + device. Selecting UART0 gives the normal mapping of UART0=ttyS0 and + UART1=ttyS1. Selecting UART1 gives the reverse mapping of UART0=ttyS1 + and UART1=ttyS0. Most people will use UART0. + +PowerPC 405 on-chip ethernet +CONFIG_IBM_OCP_ENET + If you want to use the 405 built-in ethernet select this. + +CONFIG_IBM_OCP_ENET_ERROR_MSG + Enable this option to print verbose debug messages for troubleshooting. + +PowerPC 405 on-chip ethernet -- Number of receive buffers +CONFIG_IBM_OCP_ENET_RX_BUFF + Number of ethernet receive (read) buffers. Unless you know what you + are doing the default should be fine. + +PowerPC 405 on-chip ethernet -- Number of transmit buffers +CONFIG_IBM_OCP_ENET_TX_BUFF + Number of ethernet transmit (write) buffers. Unless you know what + you are doing the default should be fine. + +PowerPC 405 on-chip ethernet -- Amount of bytes to Reserve on a skb +CONFIG_IBM_OCP_ENET_SKB_RES + Many standard ethernet drivers need to reserve 2 bytes of data + on the skb before giving the data ptr to the hardware. This is + so the IP data will be 16-byte aligned when it goes up the stack. + This is a requirement for some processors and it can cause major + slow downs on others. The 405GP dose not have problems with the + misaligned data so the default is 0. If you need to route the + incoming ethernet packets to another device that has alignment + requirements this can help remove a data copy. A value of 2 can + help at getting 16-byte aligned IP data for another device. A + larger value can be used when routing to a IP tunnel device. + Make sure XXX_DESC_SIZE - XXX_SKB_RES >= 1514, or larger if VLANS + are used. + +PPC 405 I2C Algorithm +CONFIG_PPC405_I2C_ALGO + Enable this option to use the built-in I2C on your 405. + +PPC 405 I2C Adapter +CONFIG_PPC405_I2C_ADAP + Enable this option to use the built-in I2C on your 405. /proc/efi/vars support CONFIG_EFI_VARS diff -Nru a/Makefile b/Makefile --- a/Makefile Fri Oct 17 15:52:01 2003 +++ b/Makefile Fri Oct 17 15:52:01 2003 @@ -93,6 +93,7 @@ CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ -fno-strict-aliasing -fno-common +CFLAGS += -g ifndef CONFIG_FRAME_POINTER CFLAGS += -fomit-frame-pointer endif @@ -306,8 +307,7 @@ $(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in xconfig: symlinks - $(MAKE) -C scripts kconfig.tk - wish -f scripts/kconfig.tk + @echo -e "***\n* Sorry, xconfig is broken; use \"make menuconfig\" instead.\n***" menuconfig: include/linux/version.h symlinks $(MAKE) -C scripts/lxdialog all diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c --- a/arch/i386/kernel/setup.c Fri Oct 17 15:52:01 2003 +++ b/arch/i386/kernel/setup.c Fri Oct 17 15:52:01 2003 @@ -120,6 +120,7 @@ #include #include #include +#include /* * Machine setup.. */ @@ -211,6 +212,8 @@ #define KERNEL_START (*(unsigned long *) (PARAM+0x214)) #define INITRD_START (*(unsigned long *) (PARAM+0x218)) #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) +#define EDD_NR (*(unsigned char *) (PARAM+EDDNR)) +#define EDD_BUF ((struct edd_info *) (PARAM+EDDBUF)) #define COMMAND_LINE ((char *) (PARAM+2048)) #define COMMAND_LINE_SIZE 256 @@ -715,6 +718,23 @@ return 0; } +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) +unsigned char eddnr; +struct edd_info edd[EDDMAXNR]; +/** + * copy_edd() - Copy the BIOS EDD information + * from empty_zero_page into a safe place. + * + */ +static inline void copy_edd(void) +{ + eddnr = EDD_NR; + memcpy(edd, EDD_BUF, sizeof(edd)); +} +#else +static inline void copy_edd(void) {} +#endif + /* * Do NOT EVER look at the BIOS memory size location. * It does not work on many machines. @@ -1151,6 +1171,7 @@ rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); #endif setup_memory_region(); + copy_edd(); if (!MOUNT_ROOT_RDONLY) root_mountflags &= ~MS_RDONLY; diff -Nru a/drivers/char/drm/drm_bufs.h b/drivers/char/drm/drm_bufs.h --- a/drivers/char/drm/drm_bufs.h Fri Oct 17 15:52:01 2003 +++ b/drivers/char/drm/drm_bufs.h Fri Oct 17 15:52:01 2003 @@ -106,7 +106,7 @@ switch ( map->type ) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: -#if !defined(__sparc__) && !defined(__alpha__) +#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) if ( map->offset + map->size < map->offset || map->offset < virt_to_phys(high_memory) ) { DRM(free)( map, sizeof(*map), DRM_MEM_MAPS ); diff -Nru a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h --- a/drivers/char/drm/drm_memory.h Fri Oct 17 15:52:01 2003 +++ b/drivers/char/drm/drm_memory.h Fri Oct 17 15:52:01 2003 @@ -293,6 +293,11 @@ void *DRM(ioremap)(unsigned long offset, unsigned long size) { void *pt; +#if __REALLY_HAVE_AGP + drm_map_t *map = NULL; + drm_map_list_t *r_list; + struct list_head *list; +#endif if (!size) { DRM_MEM_ERROR(DRM_MEM_MAPPINGS, @@ -300,12 +305,50 @@ return NULL; } +#if __REALLY_HAVE_AGP + if (!dev->agp || dev->agp->cant_use_aperture == 0) + goto standard_ioremap; + + list_for_each(list, &dev->maplist->head) { + r_list = (drm_map_list_t *)list; + map = r_list->map; + if (!map) continue; + if (map->offset <= offset && + (map->offset + map->size) >= (offset + size)) + break; + } + + if (map && map->type == _DRM_AGP) { + struct drm_agp_mem *agpmem; + + for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) { + if (agpmem->bound <= offset && + (agpmem->bound + (agpmem->pages + << PAGE_SHIFT)) >= (offset + size)) + break; + } + + if (agpmem == NULL) + goto ioremap_failure; + + pt = agpmem->memory->vmptr + (offset - agpmem->bound); + goto ioremap_success; + } + +standard_ioremap: +#endif if (!(pt = ioremap(offset, size))) { +#if __REALLY_HAVE_AGP +ioremap_failure: +#endif spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; spin_unlock(&DRM(mem_lock)); return NULL; } +#if __REALLY_HAVE_AGP +ioremap_success: +#endif spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; @@ -316,6 +359,11 @@ void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size) { void *pt; +#if __REALLY_HAVE_AGP + drm_map_t *map = NULL; + drm_map_list_t *r_list; + struct list_head *list; +#endif if (!size) { DRM_MEM_ERROR(DRM_MEM_MAPPINGS, @@ -323,12 +371,50 @@ return NULL; } +#if __REALLY_HAVE_AGP + if (!dev->agp || dev->agp->cant_use_aperture == 0) + goto standard_ioremap; + + list_for_each(list, &dev->maplist->head) { + r_list = (drm_map_list_t *)list; + map = r_list->map; + if (!map) continue; + if (map->offset <= offset && + (map->offset + map->size) >= (offset + size)) + break; + } + + if (map && map->type == _DRM_AGP) { + struct drm_agp_mem *agpmem; + + for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) { + if (agpmem->bound <= offset && + (agpmem->bound + (agpmem->pages + << PAGE_SHIFT)) >= (offset + size)) + break; + } + + if (agpmem == NULL) + goto ioremap_failure; + + pt = agpmem->memory->vmptr + (offset - agpmem->bound); + goto ioremap_success; + } + +standard_ioremap: +#endif if (!(pt = ioremap_nocache(offset, size))) { +#if __REALLY_HAVE_AGP +ioremap_failure: +#endif spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count; spin_unlock(&DRM(mem_lock)); return NULL; } +#if __REALLY_HAVE_AGP +ioremap_success: +#endif spin_lock(&DRM(mem_lock)); ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count; DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size; @@ -344,7 +430,11 @@ if (!pt) DRM_MEM_ERROR(DRM_MEM_MAPPINGS, "Attempt to free NULL pointer\n"); +#if __REALLY_HAVE_AGP + else if (!dev->agp || dev->agp->cant_use_aperture == 0) +#else else +#endif iounmap(pt); spin_lock(&DRM(mem_lock)); diff -Nru a/drivers/char/drm/drm_vm.h b/drivers/char/drm/drm_vm.h --- a/drivers/char/drm/drm_vm.h Fri Oct 17 15:52:01 2003 +++ b/drivers/char/drm/drm_vm.h Fri Oct 17 15:52:01 2003 @@ -368,6 +368,7 @@ drm_map_list_t *r_list; unsigned long offset = 0; struct list_head *list; + struct page *page; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", vma->vm_start, vma->vm_end, VM_OFFSET(vma)); @@ -414,28 +415,30 @@ switch (map->type) { case _DRM_AGP: -#if defined(__alpha__) - /* - * On Alpha we can't talk to bus dma address from the - * CPU, so for memory of type DRM_AGP, we'll deal with - * sorting out the real physical pages and mappings - * in nopage() - */ - vma->vm_ops = &DRM(vm_ops); - break; +#if __REALLY_HAVE_AGP + if (dev->agp->cant_use_aperture) { + /* + * On some systems we can't talk to bus dma address from + * the CPU, so for memory of type DRM_AGP, we'll deal + * with sorting out the real physical pages and mappings + * in nopage() + */ + vma->vm_ops = &DRM(vm_ops); + goto mapswitch_out; + } #endif /* fall through to _DRM_FRAME_BUFFER... */ case _DRM_FRAME_BUFFER: case _DRM_REGISTERS: - if (VM_OFFSET(vma) >= __pa(high_memory)) { + page = virt_to_page(__va(VM_OFFSET(vma))); + if (!VALID_PAGE(page) || PageReserved(page)) { #if defined(__i386__) || defined(__x86_64__) if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) { pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT; } #elif defined(__ia64__) - if (map->type != _DRM_AGP) - vma->vm_page_prot = + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); #elif defined(__powerpc__) pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED; @@ -474,6 +477,9 @@ default: return -EINVAL; /* This should never happen. */ } +#if __REALLY_HAVE_AGP +mapswitch_out: +#endif vma->vm_flags |= VM_RESERVED; /* Don't swap */ vma->vm_file = filp; /* Needed for drm_vm_open() */ diff -Nru a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c --- a/drivers/char/drm/r128_cce.c Fri Oct 17 15:52:01 2003 +++ b/drivers/char/drm/r128_cce.c Fri Oct 17 15:52:01 2003 @@ -216,7 +216,22 @@ int i; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { +#ifndef CONFIG_AGP_I460 if ( GET_RING_HEAD( &dev_priv->ring ) == dev_priv->ring.tail ) { +#else + /* + * XXX - this is (I think) a 460GX specific hack + * + * When doing texturing, ring.tail sometimes gets ahead of + * PM4_BUFFER_DL_WPTR by 2; consequently, the card processes + * its whole quota of instructions and *ring.head is still 2 + * short of ring.tail. Work around this for now in lieu of + * a better solution. + */ + if ( GET_RING_HEAD( &dev_priv->ring ) == dev_priv->ring.tail || + ( dev_priv->ring.tail - + GET_RING_HEAD( &dev_priv->ring ) ) == 2 ) { +#endif int pm4stat = R128_READ( R128_PM4_STAT ); if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >= dev_priv->cce_fifo_size ) && @@ -317,7 +332,7 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev, drm_r128_private_t *dev_priv ) { - u32 ring_start; + u32 ring_start, rptr_addr; u32 tmp; DRM_DEBUG( "\n" ); @@ -341,8 +356,24 @@ SET_RING_HEAD( &dev_priv->ring, 0 ); if ( !dev_priv->is_pci ) { - R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, - dev_priv->ring_rptr->offset ); + /* + * 460GX doesn't claim PCI writes from the card into + * the AGP aperture, so we have to get space outside + * the aperture for RPTR_ADDR. + */ + if ( dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off; + + alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA); + atomic_inc(&virt_to_page(alt_rh_off)->count); + set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags); + + dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off; + SET_RING_HEAD( &dev_priv->ring, 0 ); + rptr_addr = __pa( dev_priv->ring.head ); + } else + rptr_addr = dev_priv->ring_rptr->offset; + R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, rptr_addr ); } else { drm_sg_mem_t *entry = dev->sg; unsigned long tmp_ofs, page_ofs; @@ -629,7 +660,19 @@ DRM_ERROR( "failed to cleanup PCI GART!\n" ); } #endif - + /* + * Free the page we grabbed for RPTR_ADDR + */ + if ( !dev_priv->is_pci && dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off = + (unsigned long) dev_priv->ring.head; + struct page *p = virt_to_page((void *)alt_rh_off); + + put_page(p); + unlock_page(p); + free_page(alt_rh_off); + } + DRM(free)( dev->dev_private, sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); dev->dev_private = NULL; diff -Nru a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c --- a/drivers/char/drm/radeon_cp.c Fri Oct 17 15:52:01 2003 +++ b/drivers/char/drm/radeon_cp.c Fri Oct 17 15:52:01 2003 @@ -854,7 +854,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev, drm_radeon_private_t *dev_priv ) { - u32 ring_start, cur_read_ptr; + u32 ring_start, cur_read_ptr, rptr_addr; u32 tmp; /* Initialize the memory controller */ @@ -892,8 +892,24 @@ dev_priv->ring.tail = cur_read_ptr; if ( !dev_priv->is_pci ) { - RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, - dev_priv->ring_rptr->offset ); + /* + * 460GX doesn't claim PCI writes from the card into + * the AGP aperture, so we have to get space outside + * the aperture for RPTR_ADDR. + */ + if ( dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off; + + alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA); + atomic_inc(&virt_to_page(alt_rh_off)->count); + set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags); + + dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off; + *dev_priv->ring.head = cur_read_ptr; + rptr_addr = __pa( dev_priv->ring.head ); + } else + rptr_addr = dev_priv->ring_rptr->offset; + RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, rptr_addr ); } else { drm_sg_mem_t *entry = dev->sg; unsigned long tmp_ofs, page_ofs; @@ -1278,6 +1294,19 @@ #endif /* __REALLY_HAVE_SG */ } + /* + * Free the page we grabbed for RPTR_ADDR + */ + if ( !dev_priv->is_pci && dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off = + (unsigned long) dev_priv->ring.head; + struct page *p = virt_to_page((void *)alt_rh_off); + + put_page(p); + unlock_page(p); + free_page(alt_rh_off); + } + DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); dev->dev_private = NULL; diff -Nru a/drivers/char/drm-4.0/bufs.c b/drivers/char/drm-4.0/bufs.c --- a/drivers/char/drm-4.0/bufs.c Fri Oct 17 15:52:01 2003 +++ b/drivers/char/drm-4.0/bufs.c Fri Oct 17 15:52:01 2003 @@ -73,7 +73,7 @@ switch (map->type) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: -#ifndef __sparc__ +#if !defined(__sparc__) && !defined(__ia64__) if (map->offset + map->size < map->offset || map->offset < virt_to_phys(high_memory)) { drm_free(map, sizeof(*map), DRM_MEM_MAPS); diff -Nru a/drivers/char/drm-4.0/drmP.h b/drivers/char/drm-4.0/drmP.h --- a/drivers/char/drm-4.0/drmP.h Fri Oct 17 15:52:01 2003 +++ b/drivers/char/drm-4.0/drmP.h Fri Oct 17 15:52:01 2003 @@ -510,6 +510,8 @@ int acquired; unsigned long base; int agp_mtrr; + int cant_use_aperture; + unsigned long page_mask; } drm_agp_head_t; #endif diff -Nru a/drivers/char/drm-4.0/memory.c b/drivers/char/drm-4.0/memory.c --- a/drivers/char/drm-4.0/memory.c Fri Oct 17 15:52:01 2003 +++ b/drivers/char/drm-4.0/memory.c Fri Oct 17 15:52:01 2003 @@ -306,12 +306,44 @@ return NULL; } + if (dev->agp->cant_use_aperture) { + drm_map_t *map = NULL; + int i; + + for (i = 0; i < dev->map_count; i++) { + map = dev->maplist[i]; + if (!map) continue; + if (map->offset <= offset && + (map->offset + map->size) >= (offset + size)) + break; + } + + if (map && map->type == _DRM_AGP) { + struct drm_agp_mem *agpmem; + + for (agpmem = dev->agp->memory; agpmem; + agpmem = agpmem->next) { + if(agpmem->bound <= offset && + (agpmem->bound + (agpmem->pages + << PAGE_SHIFT)) >= (offset + size)) + break; + } + + if (agpmem) { + pt = agpmem->memory->vmptr + (offset - agpmem->bound); + goto ioremap_success; + } + } + } + if (!(pt = ioremap(offset, size))) { spin_lock(&drm_mem_lock); ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count; spin_unlock(&drm_mem_lock); return NULL; } + +ioremap_success: spin_lock(&drm_mem_lock); ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count; drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size; @@ -327,7 +359,7 @@ if (!pt) DRM_MEM_ERROR(DRM_MEM_MAPPINGS, "Attempt to free NULL pointer\n"); - else + else if (dev->agp->cant_use_aperture == 0) iounmap(pt); spin_lock(&drm_mem_lock); diff -Nru a/drivers/char/drm-4.0/mga_dma.c b/drivers/char/drm-4.0/mga_dma.c --- a/drivers/char/drm-4.0/mga_dma.c Fri Oct 17 15:52:01 2003 +++ b/drivers/char/drm-4.0/mga_dma.c Fri Oct 17 15:52:01 2003 @@ -741,10 +741,18 @@ return -ENOMEM; } - /* Write status page when secend or softrap occurs */ + /* Write status page when secend or softrap occurs + * + * Disable this on ia64 on the off chance that real status page will be + * above 4GB. + */ +#if defined(__ia64__) + MGA_WRITE(MGAREG_PRIMPTR, + virt_to_bus((void *)dev_priv->real_status_page)); +#else MGA_WRITE(MGAREG_PRIMPTR, virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003); - +#endif /* Private is now filled in, initialize the hardware */ { diff -Nru a/drivers/char/drm-4.0/r128_cce.c b/drivers/char/drm-4.0/r128_cce.c --- a/drivers/char/drm-4.0/r128_cce.c Fri Oct 17 15:52:01 2003 +++ b/drivers/char/drm-4.0/r128_cce.c Fri Oct 17 15:52:01 2003 @@ -229,7 +229,21 @@ int i; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { +#ifndef CONFIG_AGP_I460 if ( *dev_priv->ring.head == dev_priv->ring.tail ) { +#else + /* + * XXX - this is (I think) a 460GX specific hack + * + * When doing texturing, ring.tail sometimes gets ahead of + * PM4_BUFFER_DL_WPTR by 2; consequently, the card processes + * its whole quota of instructions and *ring.head is still 2 + * short of ring.tail. Work around this for now in lieu of + * a better solution. + */ + if ( (*dev_priv->ring.head == dev_priv->ring.tail) || + ((dev_priv->ring.tail - *dev_priv->ring.head) == 2) ) { +#endif int pm4stat = R128_READ( R128_PM4_STAT ); if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >= dev_priv->cce_fifo_size ) && @@ -330,7 +344,7 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev ) { drm_r128_private_t *dev_priv = dev->dev_private; - u32 ring_start; + u32 ring_start, rptr_addr; u32 tmp; /* The manual (p. 2) says this address is in "VM space". This @@ -342,10 +356,27 @@ R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 ); R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 ); + /* + * 460GX doesn't claim PCI writes from the card into the AGP + * aperture, so we have to get space outside the aperture for + * RPTR_ADDR. + */ + if ( dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off; + + alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA); + atomic_inc(&virt_to_page(alt_rh_off)->count); + set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags); + + dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off; + rptr_addr = __pa( dev_priv->ring.head ); + } else { + rptr_addr = dev_priv->ring_rptr->offset; + } + /* DL_RPTR_ADDR is a physical address in AGP space. */ *dev_priv->ring.head = 0; - R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, - dev_priv->ring_rptr->offset ); + R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, rptr_addr ); /* Set watermark control */ R128_WRITE( R128_PM4_BUFFER_WM_CNTL, @@ -529,6 +560,19 @@ DO_REMAPFREE( dev_priv->agp_textures ); } #endif + + /* + * Free the page we grabbed for RPTR_ADDR + */ + if ( dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off = + (unsigned long) dev_priv->ring.head; + + atomic_dec(&virt_to_page(alt_rh_off)->count); + clear_bit(PG_locked, &virt_to_page(alt_rh_off)->flags); + wake_up(&virt_to_page(alt_rh_off)->wait); + free_page(alt_rh_off); + } drm_free( dev->dev_private, sizeof(drm_r128_private_t), DRM_MEM_DRIVER ); diff -Nru a/drivers/char/drm-4.0/radeon_cp.c b/drivers/char/drm-4.0/radeon_cp.c --- a/drivers/char/drm-4.0/radeon_cp.c Fri Oct 17 15:52:01 2003 +++ b/drivers/char/drm-4.0/radeon_cp.c Fri Oct 17 15:52:01 2003 @@ -569,7 +569,7 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev ) { drm_radeon_private_t *dev_priv = dev->dev_private; - u32 ring_start, cur_read_ptr; + u32 ring_start, cur_read_ptr, rptr_addr; u32 tmp; /* Initialize the memory controller */ @@ -592,10 +592,29 @@ /* Initialize the ring buffer's read and write pointers */ cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); + *dev_priv->ring.head = cur_read_ptr; dev_priv->ring.tail = cur_read_ptr; - RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, dev_priv->ring_rptr->offset ); + /* + * 460GX doesn't claim PCI writes from the card into the AGP + * aperture, so we have to get space outside the aperture for + * RPTR_ADDR. + */ + if ( dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off; + + alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA); + atomic_inc(&virt_to_page(alt_rh_off)->count); + set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags); + + dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off; + *dev_priv->ring.head = cur_read_ptr; + rptr_addr = __pa( dev_priv->ring.head ); + } else + rptr_addr = dev_priv->ring_rptr->offset; + + RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, rptr_addr); /* Set ring buffer size */ RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw ); @@ -836,6 +855,19 @@ DO_IOREMAPFREE( dev_priv->agp_textures ); } #endif + + /* + * Free the page we grabbed for RPTR_ADDR. + */ + if ( dev->agp->agp_info.chipset == INTEL_460GX ) { + unsigned long alt_rh_off = + (unsigned long) dev_priv->ring.head; + + atomic_dec(&virt_to_page(alt_rh_off)->count); + clear_bit(PG_locked, &virt_to_page(alt_rh_off)->flags); + wake_up(&virt_to_page(alt_rh_off)->wait); + free_page(alt_rh_off); + } drm_free( dev->dev_private, sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile --- a/drivers/scsi/Makefile Fri Oct 17 15:52:01 2003 +++ b/drivers/scsi/Makefile Fri Oct 17 15:52:01 2003 @@ -97,7 +97,7 @@ obj-$(CONFIG_SCSI_NCR53C7xx) += 53c7,8xx.o subdir-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2 ifeq ($(CONFIG_SCSI_SYM53C8XX_2),y) - obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/sym53c8xx.o + obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/sym53c8xx_2.o endif obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o obj-$(CONFIG_SCSI_NCR53C8XX) += ncr53c8xx.o